package com.pureut.storage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.storage.domain.*;
import com.pureut.storage.dto.*;
import com.pureut.storage.export.SubcontractPurchaseReceiptExport;
import com.pureut.storage.mapper.*;
import com.pureut.storage.service.*;
import com.pureut.storage.util.UnitUtil;
import com.pureut.storage.utils.DocumentTypeEnum;
import com.pureut.storage.utils.GenerationMethodEnum;
import com.pureut.storage.utils.VariousKeyEnum;
import com.pureut.storage.vo.*;
import com.sale.common.core.constant.CacheNames;
import com.sale.common.core.exception.GlobalException;
import com.sale.common.dict.utils.DictUtils;
import com.sale.common.mybatis.core.page.PageQuery;
import com.sale.common.mybatis.core.page.TableDataInfo;
import com.sale.common.redis.utils.CacheUtils;
import com.sale.common.redis.utils.RedisUtils;
import com.sale.common.satoken.utils.LoginHelper;
import com.sale.system.api.RemoteCodeService;
import com.sale.system.api.RemoteSysConverterService;
import com.sale.system.api.RemoteUnitService;
import com.sale.system.api.domain.SysAuxiliary;
import com.sale.system.api.domain.SysDictData;
import com.sale.system.api.domain.dto.SysConverterManagementDto;
import com.sale.system.api.model.MaterialUnitDto;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/***
 * 委外入库实现层
 * Author:C
 * Date:2022/12/27 16:35
 * @DESC
 */
@Service
public class SubcontractReceiptServiceImpl extends ServiceImpl<SubcontractReceiptMapper, SubcontractReceipt> implements SubcontractReceiptService {

    @Resource
    SubcontractReceiptMapper subcontractReceiptMapper;

//    @Resource
//    OrderFeignService orderFeignService;

    @Resource
    WarehouseService warehouseService;

//    @Resource
//    FeignService orderFeignService;

//    @Resource
//    SchedulingPlanFeignService schedulingPlanFeignService;

    @Lazy
    @Resource
    IncomingMaterialSubcontractPrintingService incomingMaterialSubcontractPrintingService;

    @Resource
    IncomingMaterialPrintingDetailService incomingMaterialPrintingDetailService;

    @Resource
    SubcontractReceiptDetailMapper subcontractReceiptDetailMapper;

    @Resource
    IncomingMaterialSubcontractPrintingMapper incomingMaterialSubcontractPrintingMapper;

    @Resource
    IncomingMaterialPrintingMapper incomingMaterialPrintingMapper;

    @Resource
    IncomingMaterialPrintingService incomingMaterialPrintingService;

    @Resource
    WmsStockInfoMapper wmsStockInfoMapper;

    @Resource
    WmsStockInfoService wmsStockInfoService;

    @Resource
    SubcontractReceiptDetailService subcontractReceiptDetailService;

    @Resource
    PublicMaterialMapper publicMaterialMapper;

//    @Resource
//    QualityFeginService qualityFeginService;

//    @Resource
//    SystemDocumentFeignService systemDocumentFeignService;

//    @Resource
//    ConverterManagementService converterManagementService;

    @DubboReference
    RemoteCodeService remoteCodeService;

    @DubboReference
    RemoteUnitService remoteUnitService;

    @DubboReference
    RemoteSysConverterService remoteSysConverterService;

    @Resource
    UnitUtil unitUtil;


    /**
     * 委外入库列表
     *
     * @param subcontractReceiptVo
     * @return
     */
    @Override
    public TableDataInfo<SubcontractReceiptDto> getReceiptList(SubcontractReceiptVo subcontractReceiptVo, PageQuery pageQuery) throws Exception {
        Page<SubcontractReceiptDto> subcontractList = subcontractReceiptMapper.getSubcontractList(subcontractReceiptVo, pageQuery.build());
        //单位集合
        Map<String, MaterialUnitDto> unitByCodeToMap = remoteUnitService.getUnitByCodeToMap();
        //获取委外入库状态字典值
        List<SysDictData> receiptArray = DictUtils.getDictCache("subcontract_receipt_status");
        Map<String, String> subcontractReceiptMap = receiptArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取委外入库收发类型
        List<SysDictData> rdArray = DictUtils.getDictCache("subcontract_receipt_rd_type");
        Map<String, String> rdMap = rdArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        List<SubcontractReceiptDto> records = subcontractList.getRecords();
        for (SubcontractReceiptDto entity : records) {
            //委外入库状态
            entity.setStatusDict(subcontractReceiptMap.get(String.valueOf(entity.getStatus())));
            //单据类型
            entity.setDocumentTypeDict(DocumentTypeEnum.getValue(Integer.parseInt(entity.getDocumentType())));
            //收发类型
            entity.setReceiveTypeDict(rdMap.get(entity.getReceiveType()));
            //生成方式
            entity.setGenerationMethodDict(GenerationMethodEnum.getValue(entity.getGenerationMethod()));

            if (entity.getMaterialUnit() != null) {
                //单位
                entity.setUnitDict(unitByCodeToMap.get(entity.getMaterialUnit()).getUnitName());
            }

            //辅助属性
            List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + entity.getTenantId(), String.valueOf(entity.getMaterialId()));
            entity.setAuxiliaryAttribute(statsArray);
//            if (entity.getMaterialMoreUnit() != null) {
//                //转换
//                UnitConversionDto unitConversionDto = unitUtil.atWillunitConversion(entity.getMaterialUnit(), entity.getMaterialCode(),
//                    String.valueOf(entity.getPlannedWeight()), entity.getMaterialId());
//                if (unitConversionDto != null) {
//                    entity.setUnitConversion(unitConversionDto.getMaterialMoreUnitNumber());
//                }
//            }
            //单位转换
            String s = unitUtil.unitC(entity.getMaterialCode(),
                String.valueOf(entity.getPlannedWeight()),
                entity.getMaterialId(),
                unitByCodeToMap.get(entity.getMaterialUnit()).getUnitName());
            entity.setUnitConversion(s);
//            //免检标识
//            InspectionMarkVo inspectionMarkVo = new InspectionMarkVo();
//            inspectionMarkVo.setConverterId(entity.getConverterId());
//            inspectionMarkVo.setMaterialCode(entity.getMaterialCode());
//            AjaxResult inspectionMark = qualityFeginService.getInspectionMark(inspectionMarkVo);
//            if (inspectionMark == null) {
//                entity.setInspectionExemption(2);
//            } else {
//                QualityInspectionManagementDto data = JSON.parseObject(JSON.toJSONString(inspectionMark.get("data")), QualityInspectionManagementDto.class);
//                if (data.getId() == null) {
//                    entity.setInspectionExemption(2);
//                } else {
//                    entity.setInspectionExemption(data.getStatus());
//                }
//            }
        }
        return TableDataInfo.build(subcontractList);
    }

    /**
     * 委外入库新增
     *
     * @param subcontractReceiptVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addSubcontractReceipt(SubcontractReceiptVo subcontractReceiptVo) throws Exception {
        List<PurchaseVo> procurementList = subcontractReceiptVo.getProcurementList();
        List<SubcontractReceipt> subcontractReceiptList = new ArrayList<>();
        if (procurementList.size() > 0) {
            for (PurchaseVo entity : procurementList) {
                SubcontractReceipt subcontractReceipt = new SubcontractReceipt();
                String authorityCoding = remoteCodeService.authorityCoding("warehouse:warehousing:subcontracting:list");
                if (authorityCoding == null) {
                    throw new GlobalException("该单据未进行配置，无法生成单据编码");
                }
                subcontractReceipt.setReceiptNo(authorityCoding)
                    .setDeptId(LoginHelper.getDeptId())
                    .setStatus(1)
                    .setSubcontractOrderNo(entity.getSubcontractOrderNo())
                    .setMaterialId(entity.getMaterialId())
                    .setMaterialCode(entity.getMaterialCode())
                    .setMaterialCategory(entity.getMaterialCategory())
                    .setPlannedWeight(entity.getPlannedWeight())
                    .setWarehousingWarehouse(Long.parseLong(entity.getWarehousingWarehouse()))
                    .setConverterId(subcontractReceiptVo.getConverterId())
                    .setEstimatedTime(subcontractReceiptVo.getEstimatedTime())
                    .setRemark(subcontractReceiptVo.getRemark())
                    .setDrawerBy(LoginHelper.getUsername())
                    .setDrawerTime(new Date())
                    .setMaterialUnit(entity.getMaterialUnit())
                    .setReceiveType(subcontractReceiptVo.getReceiveType())
                    .setDocumentType(DocumentTypeEnum.SUBCONTRACT_RECEIPT.getCode())
                    .setGenerationMethod(GenerationMethodEnum.MANUALLY_GENERATED.getCode());
                subcontractReceiptList.add(subcontractReceipt);
            }
            return saveBatch(subcontractReceiptList);
        } else {
            throw new GlobalException("请至少选择一条数据");
        }
    }

    /**
     * 新增委外入库（自动新增 其他模块插入数据时使用）
     *
     * @param subcontractReceiptOtherVo
     * @return
     * @throws Exception
     */
    @Override
    public boolean addOtherSubcontractReceipt(SubcontractReceiptOtherVo subcontractReceiptOtherVo) throws Exception {
//        List<PurchaseVo> procurementList = subcontractReceiptVo.getProcurementList();
//        List<SubcontractReceipt> subcontractReceiptList = new ArrayList<>();


        SubcontractReceipt subcontractReceipt = new SubcontractReceipt();
        String authorityCoding = remoteCodeService.authorityCoding("warehouse:warehousing:subcontracting:list");
        if (authorityCoding == null) {
            throw new GlobalException("该单据未进行配置，无法生成单据编码");
        }
        subcontractReceipt.setReceiptNo(authorityCoding)
            .setDeptId(LoginHelper.getDeptId())
            .setStatus(1)
            .setSubcontractOrderNo(subcontractReceiptOtherVo.getSubcontractingOrderNum())
            .setMaterialId(subcontractReceiptOtherVo.getMaterialId())
            .setMaterialCode(subcontractReceiptOtherVo.getMaterialCode())
            .setMaterialCategory(Integer.parseInt(subcontractReceiptOtherVo.getMaterialType()))
            .setPlannedWeight(Double.parseDouble(subcontractReceiptOtherVo.getSubcontractingWeight()))
            .setConverterId(subcontractReceiptOtherVo.getConverterId())
//                .setEstimatedTime(subcontractReceiptOtherVo.getEstimatedTime())
//                .setRemark(subcontractReceiptOtherVo.getRemark())
            .setDrawerBy(LoginHelper.getUsername())
            .setDrawerTime(new Date())
            .setEstimatedTime(subcontractReceiptOtherVo.getDemandTime())
            .setDocumentType(DocumentTypeEnum.SUBCONTRACT_RECEIPT.getCode())
            .setGenerationMethod(GenerationMethodEnum.AUTO_GENERATE.getCode());
        if ("4".equals(subcontractReceiptOtherVo.getMaterialType())) {
            subcontractReceipt.setReceiveType(1);
        }
        if ("3".equals(subcontractReceiptOtherVo.getMaterialType())) {
            subcontractReceipt.setReceiveType(2);
        }
        return save(subcontractReceipt);

    }

    /**
     * 关结委外入库
     *
     * @param subcontractReceiptVo
     * @return
     */
    @Override
    public boolean close(SubcontractReceiptVo subcontractReceiptVo) {
        SubcontractReceipt subcontractReceipt = getById(subcontractReceiptVo.getId());

        //判断来料打印中是否都已完成，否则不让关结
        List<IncomingMaterialPrinting> incomingMaterialPrintings = incomingMaterialPrintingMapper.selectList(new QueryWrapper<IncomingMaterialPrinting>().lambda()
            .eq(IncomingMaterialPrinting::getReceiptNo, subcontractReceipt.getReceiptNo())
            .ne(IncomingMaterialPrinting::getPrintStatus, 4));

        if (incomingMaterialPrintings.size() != 0) {
            throw new GlobalException("存在未完成的来料打印单,不能关结");
        }
        //已完成、已关结不可重复关结；
        if (subcontractReceipt.getStatus() != 4 || subcontractReceipt.getStatus() != 5) {
            //待入库、部分入库状态的单据关结后，单据状态更新为“已关结”，无影响；
            //入库中的单据关结后，单据状态更新为“已关结”，已扫描过的条码为在库（委外入库未扫描的条码从库存中删除）
            if (subcontractReceipt.getStatus() == 2) {
                // 入库中和部分入库的单据关结后，单据状态更新为“已关结”，已扫描过的条码为在库（委外入库未扫描的条码从库存中删除）
                List<SubcontractReceiptDetail> subcontractReceiptDetails = subcontractReceiptDetailMapper.selectList(new QueryWrapper<SubcontractReceiptDetail>()
                    .lambda().eq(SubcontractReceiptDetail::getSubcontractId, subcontractReceipt.getId()));
                if (subcontractReceiptDetails.size() > 0) {
                    //获取未扫描的明细数据
                    List<String> materialNumberList = subcontractReceiptDetails.stream()
                        .filter(t -> t.getStatus() == 1)
                        .map(SubcontractReceiptDetail::getMaterialNumber)
                        .collect(Collectors.toList());
                    //将对应号码的数据在仓库中进行删除
                    if (materialNumberList.size() > 0) {
                        List<WmsStockInfo> wmsStockInfos = wmsStockInfoMapper.selectList(new QueryWrapper<WmsStockInfo>()
                            .lambda().in(WmsStockInfo::getWsiMaterialNumber, materialNumberList));
                        wmsStockInfoService.deleteBatch(wmsStockInfos);
                    }
                }
            }
            subcontractReceipt.setStatus(5)
                .setCloseReason(subcontractReceiptVo.getCloseReason())
                .setClosingBy(LoginHelper.getUsername())
                .setClosingTime(new Date());
            return updateById(subcontractReceipt);
        } else {
            throw new GlobalException("已完成、已关结不可重复关结");
        }
    }

    /**
     * 查看
     *
     * @param id
     * @return
     */
    @Override
    public SubcontractReceiptDto getView(Long id) {

        //根据id获取明细对象
        SubcontractReceiptDto subcontractReceiptDto = subcontractReceiptMapper.getSubcontractById(id);

        subcontractReceiptDto.setDocumentType(String.valueOf(subcontractReceiptDto.getDocumentType()));
        //单位集合
        Map<String, MaterialUnitDto> unitByCodeToMap = remoteUnitService.getUnitByCodeToMap();
        //单据类型
        subcontractReceiptDto.setDocumentTypeDict(DocumentTypeEnum.getValue(Integer.parseInt(subcontractReceiptDto.getDocumentType())));
        //收发类型
        List<SysDictData> typeArray = DictUtils.getDictCache("subcontract_receipt_rd_type");
        Map<String, String> purchaseReceiptMap = typeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        subcontractReceiptDto.setReceiveTypeDict(purchaseReceiptMap.get(subcontractReceiptDto.getReceiveType()));
        subcontractReceiptDto.setReceiveType(String.valueOf(subcontractReceiptDto.getReceiveType()));

        List<PurchaseVo> purchaseVos = new ArrayList<>();
        PurchaseVo purchaseVo = new PurchaseVo();
        purchaseVo.setSubcontractOrderNo(subcontractReceiptDto.getSubcontractOrderNo());
        purchaseVo.setPlannedWeight(subcontractReceiptDto.getPlannedWeight());
        purchaseVo.setWarehousingWarehouse(String.valueOf(subcontractReceiptDto.getWarehousingWarehouse()));
        //单位
        purchaseVo.setMaterialUnit(subcontractReceiptDto.getMaterialUnit());
        purchaseVo.setUnitDict(unitByCodeToMap.get(subcontractReceiptDto.getMaterialUnit()).getUnitName());
        //辅助属性
        List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + subcontractReceiptDto.getTenantId(), String.valueOf(subcontractReceiptDto.getMaterialId()));
        purchaseVo.setAuxiliaryAttribute(statsArray);
        //物料信息
        purchaseVo.setMaterialName(subcontractReceiptDto.getMaterialName());
        purchaseVo.setMaterialCode(subcontractReceiptDto.getMaterialCode());
        purchaseVo.setMaterialSpec(subcontractReceiptDto.getMaterialSpec());
        //仓库
        purchaseVo.setWarehousingWarehouseDict(subcontractReceiptDto.getWarehouseName());
        purchaseVos.add(purchaseVo);
        subcontractReceiptDto.setProcurementList(purchaseVos);
        return subcontractReceiptDto;
    }

    /**
     * 修改委外入库
     *
     * @param subcontractReceiptVo
     * @return
     */
    @Override
    public boolean updateSubcontractReceipt(SubcontractReceiptVo subcontractReceiptVo) {
        SubcontractReceipt subcontractReceipt = getById(subcontractReceiptVo.getId());
        if (subcontractReceipt.getStatus() == 1) {
            subcontractReceipt.setReceiveType(subcontractReceiptVo.getReceiveType());
            subcontractReceipt.setConverterId(subcontractReceiptVo.getConverterId());
            subcontractReceipt.setEstimatedTime(subcontractReceiptVo.getEstimatedTime());
            subcontractReceipt.setRemark(subcontractReceiptVo.getRemark());
            List<PurchaseVo> procurementList = subcontractReceiptVo.getProcurementList();
            for (PurchaseVo entity : procurementList) {
                subcontractReceipt.setSubcontractOrderNo(entity.getSubcontractOrderNo())
                    .setMaterialUnit(entity.getMaterialUnit())
                    .setPlannedWeight(entity.getPlannedWeight())
                    .setWarehousingWarehouse(Long.parseLong(entity.getWarehousingWarehouse()))
                    .setMaterialCode(entity.getMaterialCode())
                    .setMaterialId(entity.getMaterialId());
            }
            return updateById(subcontractReceipt);
        } else {
            throw new GlobalException("只能修改待入库的数据");
        }

    }

    /**
     * 删除委外入库
     *
     * @param idStr
     * @return
     */
    @Override
    public boolean deleteSubcontractReceipt(String idStr) {
        List<String> idList = Arrays.asList(idStr.split(","));
        if (idList.size() == 0) {
            throw new GlobalException("请至少选择一条数据");
        }
        List<SubcontractReceipt> subcontractReceiptList = new ArrayList<>();
        List<SubcontractReceipt> subcontractReceipts = subcontractReceiptMapper.selectList(new QueryWrapper<SubcontractReceipt>().lambda().in(SubcontractReceipt::getId, idList));
        for (SubcontractReceipt entity : subcontractReceipts) {
            if (entity.getStatus() == 1) {
                subcontractReceiptList.add(entity);
            } else {
                throw new GlobalException("只能删除待入库的单据");
            }
        }
        List<SubcontractReceipt> deleteList = new ArrayList<>();
        for (SubcontractReceipt entity : subcontractReceiptList) {
            if (entity.getGenerationMethod() == 2) {
                deleteList.add(entity);
            } else {
                throw new GlobalException("自动生成的单据不能删除");
            }
        }
        return removeByIds(deleteList);
    }

    /**
     * (委外入库打印)入库/送检
     *
     * @param warehousInspectionVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean subcontractWarehousInspection(WarehousInspectionVo warehousInspectionVo) throws Exception {

        SubcontractReceipt subcontractReceipt = subcontractReceiptMapper.selectById(warehousInspectionVo.getId());

        //获取加工商信息
        SysConverterManagementDto converterById = remoteSysConverterService.getConverterById(subcontractReceipt.getConverterId());
        if (subcontractReceipt.getStatus() == 1 || subcontractReceipt.getStatus() == 2) {
            //修改状态为入库中
            subcontractReceipt.setStatus(2);
            subcontractReceipt.setMaterialUnit(warehousInspectionVo.getMaterialUnit());
            List<IncomingMaterialPrintingDetail> incomingMaterialPrintingDetails = new ArrayList<>();
            IncomingMaterialPrinting incomingMaterialPrinting = new IncomingMaterialPrinting();
            incomingMaterialPrinting.setDocumentType(subcontractReceipt.getDocumentType())
                .setDeptId(LoginHelper.getDeptId())
                .setReceiptNo(subcontractReceipt.getReceiptNo())
                .setConverterCode(converterById.getConverterNum())
                .setQuantityBatch(warehousInspectionVo.getNumberCars())
                .setCreateBy(LoginHelper.getUsername())
                .setCreateTime(new Date())
                //唯一标识
                .setOnlyMark(remoteCodeService.splitList("IMP"))
                //生成批次号
                .setBatchNo(batchNoGenerate())
                .setMaterialCode(subcontractReceipt.getMaterialCode());
//                //如果是免检就保存打印状态为待打印，如果不是就保存待检验
//                if (warehousInspectionVo.getInspectionExemption() == 1) {
//                    incomingMaterialPrinting.setPrintStatus(2);
//                } else {
//                    incomingMaterialPrinting.setPrintStatus(1);
//                }
            incomingMaterialPrinting.setPrintStatus(2);
            incomingMaterialPrintingMapper.insert(incomingMaterialPrinting);
            //存储打印明细数据
            for (int i = 0; i <= warehousInspectionVo.getNumberCars() - 1; i++) {
                IncomingMaterialPrintingDetail incomingMaterialPrintingDetail = new IncomingMaterialPrintingDetail();
                incomingMaterialPrintingDetail.setPrintId(incomingMaterialPrinting.getId())
                    .setBatchNo(incomingMaterialPrinting.getBatchNo())
                    .setReceiptQuantity(1)
                    .setMaterialCategory(subcontractReceipt.getMaterialCategory())
                    .setMaterialId(subcontractReceipt.getMaterialId())
                    .setMaterialCode(incomingMaterialPrinting.getMaterialCode())
                    .setMaterialNumber(remoteCodeService.splitList("CGRKDYNUM"))
                    .setMaterialUnit(warehousInspectionVo.getMaterialUnit())
                    .setReceiptId(subcontractReceipt.getId())
                    .setNetWeight(Double.parseDouble(warehousInspectionVo.getUnitContent()));
//                    //如果是免检就保存净重和毛重数据
//                    if (warehousInspectionVo.getInspectionExemption() == 1) {
//                        incomingMaterialPrintingDetail.setGrossWeight(entity.getNetWeight() / entity.getNumberCars());
//                        incomingMaterialPrintingDetail.setNetWeight(entity.getNetWeight() / entity.getNumberCars());
//                    } else {
//                        incomingMaterialPrintingDetail.setGrossWeight(entity.getNetWeight() / entity.getNumberCars());
//                    }
                incomingMaterialPrintingDetails.add(incomingMaterialPrintingDetail);
            }
            incomingMaterialPrintingDetailService.batchSave(incomingMaterialPrintingDetails);

            return subcontractReceiptMapper.updateById(subcontractReceipt) > 0;
        } else {
            throw new GlobalException("只能操作待入库或者入库中的数据");
        }
    }

    /**
     * 导出
     *
     * @param subcontractReceiptVo
     * @return
     */
    @Override
    public List<SubcontractPurchaseReceiptExport> getInfoExport(SubcontractReceiptVo subcontractReceiptVo) {
        List<SubcontractPurchaseReceiptExportDto> subcontractList;
        if (subcontractReceiptVo.getIdStr() == null) {
            subcontractList = subcontractReceiptMapper.getSubcontractListOut(subcontractReceiptVo);

        } else {
            List<String> idList = Arrays.asList(subcontractReceiptVo.getIdStr().split(","));
            //获取勾选的数据列表
            subcontractList = subcontractReceiptMapper.getDataByIdStr(idList);
        }
        //获取网型标准缓存字典数据
        List<SysDictData> netArray = DictUtils.getDictCache("sys_of_type");
        Map<String, String> netMap = netArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取铺网类型标准缓存字典数据
        List<SysDictData> netTypeArray = DictUtils.getDictCache("sys_type_net");
        Map<String, String> netTypeMap = netTypeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //获取委外入库收发类型
        List<SysDictData> rdArray = DictUtils.getDictCache("subcontract_receipt_rd_type");
        Map<String, String> rdMap = rdArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        List<SubcontractPurchaseReceiptExport> subcontractPurchaseReceiptExportList = new ArrayList<>();
        for (SubcontractPurchaseReceiptExportDto entity : subcontractList) {
            SubcontractPurchaseReceiptExport subcontractPurchaseReceiptExport = new SubcontractPurchaseReceiptExport();
            BeanUtils.copyProperties(entity, subcontractPurchaseReceiptExport);
            //加工商
            subcontractPurchaseReceiptExport.setConverterName(entity.getConverterName());

            //收发类型
            if (!"0".equals(entity.getReceiveType())) {
                subcontractPurchaseReceiptExport.setReceiveType(rdMap.get(String.valueOf(entity.getReceiveType())));
            } else {
                subcontractPurchaseReceiptExport.setReceiveType("");
            }

            subcontractPurchaseReceiptExport.setMaterialNetDict(netMap.get(entity.getMaterialNetDict()));
            subcontractPurchaseReceiptExport.setMaterialNetTypeDict(netTypeMap.get(entity.getMaterialNetTypeDict()));

            subcontractPurchaseReceiptExportList.add(subcontractPurchaseReceiptExport);
        }
        return subcontractPurchaseReceiptExportList;
    }

    /**
     * 委外入库（pda）
     *
     * @param pickingRestDbVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PickingRestDbDto subcontractPda(PickingRestDbVo pickingRestDbVo) {
        PickingRestDbDto pickingRestDbDto = new PickingRestDbDto();
        SubcontractReceipt subcontractReceipt = getById(pickingRestDbVo.getId());
        //单位集合
        Map<String, MaterialUnitDto> unitByCodeToMap = remoteUnitService.getUnitByCodeToMap();
        if (subcontractReceipt.getStatus() == 1 || subcontractReceipt.getStatus() == 2 || subcontractReceipt.getStatus() == 3) {
            //扫码入库
            if ("1".equals(pickingRestDbVo.getType())) {
                //如果是第一步，需要查询库位信息
                if (pickingRestDbVo.getExecutionOrder() == 1) {
                    WarehouseStringDto warehouseCode = warehouseService.getWarehouseCode(pickingRestDbVo.getInputValue());
                    if (warehouseCode.getCombinationName() == null) {
                        pickingRestDbDto.setMessage("该仓库不存在，请核实");
                        pickingRestDbDto.setCode("500");
                        return pickingRestDbDto;
                    }
                    pickingRestDbDto.setWarehouseMessage(warehouseCode.getCombinationName());
                    pickingRestDbDto.setCkId(warehouseCode.getCkId());
                    pickingRestDbDto.setKqId(warehouseCode.getKqId());
                    pickingRestDbDto.setKwId(warehouseCode.getKwId());
                    pickingRestDbDto.setCode("200");
                    return pickingRestDbDto;
                }
                //如果是第二步，需要根据物料号码查询明细信息
                if (pickingRestDbVo.getExecutionOrder() == 2) {
                    SubcontractReceiptDetail subcontractReceiptDetail = subcontractReceiptDetailMapper.selectOne(new QueryWrapper<SubcontractReceiptDetail>()
                        .lambda()
                        .eq(SubcontractReceiptDetail::getSubcontractId, subcontractReceipt.getId())
                        .eq(SubcontractReceiptDetail::getMaterialNumber, pickingRestDbVo.getInputValue()));
                    if (subcontractReceiptDetail == null) {
                        pickingRestDbDto.setMessage("未查询到对应数据，请核实");
                        pickingRestDbDto.setCode("500");
                        return pickingRestDbDto;
                    }

                    if (subcontractReceiptDetail.getStatus() == 2) {
                        pickingRestDbDto.setMessage("该数据已经入库");
                        pickingRestDbDto.setCode("500");
                        return pickingRestDbDto;
                    }

                    PublicMaterial publicMaterial = publicMaterialMapper.selectOne(new QueryWrapper<PublicMaterial>()
                        .lambda().eq(PublicMaterial::getMaterialCode, subcontractReceiptDetail.getMaterialCode()));
//                    //获取单位字典值
//                    List<SysDictData> unitArray = DictUtils.getDictCache("sys_material_unit");
//                    Map<String, String> unitMap = unitArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
                    MaterialUnitDto materialUnitDto = unitByCodeToMap.get(String.valueOf(publicMaterial.getMaterialUnit()));
                    if (subcontractReceipt.getActualQuantity() == null) {
                        subcontractReceipt.setActualQuantity(String.valueOf(subcontractReceiptDetail.getNetWeight()));
                        //修改采购入库信息入库重量
                        subcontractReceipt.setWarehousingWeight(subcontractReceiptDetail.getNetWeight());
                        subcontractReceipt.setWarehousingNum(Integer.parseInt(String.valueOf(subcontractReceiptDetail.getReceiptQuantity())));
                    } else {
                        BigDecimal bigDecimal = new BigDecimal(subcontractReceipt.getActualQuantity());
                        BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(subcontractReceiptDetail.getNetWeight()));
                        String s = bigDecimal.add(bigDecimal1).toString();
                        subcontractReceipt.setActualQuantity(s);
                        //修改采购入库信息入库重量
                        BigDecimal bigDecimal2 = new BigDecimal(String.valueOf(subcontractReceipt.getWarehousingWeight()));
                        BigDecimal bigDecimal3 = new BigDecimal(String.valueOf(subcontractReceiptDetail.getNetWeight()));
                        String s1 = bigDecimal2.add(bigDecimal3).toString();
                        subcontractReceipt.setWarehousingWeight(Double.parseDouble(s1));
                        BigDecimal bigDecimal4 = new BigDecimal(subcontractReceipt.getWarehousingNum());
                        BigDecimal bigDecimal5 = new BigDecimal(String.valueOf(subcontractReceiptDetail.getReceiptQuantity()));
                        int i = Integer.parseInt(bigDecimal4.add(bigDecimal5).toString());
                        subcontractReceipt.setWarehousingNum(i);
                    }


//                    //判断单位
//                    if ("2".equals(publicGoods.getMaterialUnit())) {
//                        //如果单位是千克
//                        if (subcontractReceipt.getActualQuantity() == null) {
//                            subcontractReceipt.setActualQuantity(String.valueOf(subcontractReceiptDetail.getNetWeight()));
//                            //修改采购入库信息入库重量
//                            subcontractReceipt.setWarehousingWeight(subcontractReceiptDetail.getNetWeight());
//                            subcontractReceipt.setWarehousingNum(Integer.parseInt(String.valueOf(subcontractReceiptDetail.getReceiptQuantity())));
//                        } else {
//                            BigDecimal bigDecimal = new BigDecimal(subcontractReceipt.getActualQuantity());
//                            BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(subcontractReceiptDetail.getNetWeight()));
//                            String s = bigDecimal.add(bigDecimal1).toString();
//                            subcontractReceipt.setActualQuantity(s);
//                            //修改采购入库信息入库重量
//                            BigDecimal bigDecimal2 = new BigDecimal(String.valueOf(subcontractReceipt.getWarehousingWeight()));
//                            BigDecimal bigDecimal3 = new BigDecimal(String.valueOf(subcontractReceiptDetail.getNetWeight()));
//                            String s1 = bigDecimal2.add(bigDecimal3).toString();
//                            subcontractReceipt.setWarehousingWeight(Double.parseDouble(s1));
//                            BigDecimal bigDecimal4 = new BigDecimal(subcontractReceipt.getWarehousingNum());
//                            BigDecimal bigDecimal5 = new BigDecimal(String.valueOf(subcontractReceiptDetail.getReceiptQuantity()));
//                            int i = Integer.parseInt(bigDecimal4.add(bigDecimal5).toString());
//                            subcontractReceipt.setWarehousingNum(i);
//                        }
//                    } else if ("3".equals(publicGoods.getMaterialUnit())) {
//                        //如果单位是吨，若单位为吨，则实际量=入库重量（kg）/1000
//                        if (subcontractReceipt.getActualQuantity() == null) {
//                            BigDecimal bigDecimal = new BigDecimal(String.valueOf(subcontractReceiptDetail.getNetWeight()));
//                            BigDecimal divide = bigDecimal.divide(new BigDecimal("1000"));
//                            subcontractReceipt.setActualQuantity(divide.toString());
//                            //修改采购入库信息入库重量
//                            //修改采购入库信息入库重量
//                            BigDecimal bigDecimal2 = new BigDecimal(String.valueOf(subcontractReceipt.getWarehousingWeight()));
//                            BigDecimal bigDecimal3 = new BigDecimal(String.valueOf(subcontractReceiptDetail.getNetWeight()));
//                            String s1 = bigDecimal2.add(bigDecimal3).toString();
//                            subcontractReceipt.setWarehousingWeight(Double.parseDouble(s1));
//                            BigDecimal bigDecimal4 = new BigDecimal(subcontractReceipt.getWarehousingNum());
//                            BigDecimal bigDecimal5 = new BigDecimal(String.valueOf(subcontractReceiptDetail.getReceiptQuantity()));
//                            int i = Integer.parseInt(bigDecimal4.add(bigDecimal5).toString());
//                            subcontractReceipt.setWarehousingNum(i);
//                        } else {
//                            BigDecimal bigDecimal = new BigDecimal(subcontractReceipt.getActualQuantity());
//                            BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(subcontractReceiptDetail.getNetWeight()));
//                            BigDecimal divide = bigDecimal1.divide(new BigDecimal("1000"));
//                            String s = bigDecimal.add(divide).toString();
//                            subcontractReceipt.setActualQuantity(s);
//                            //修改采购入库信息入库重量
//                            //修改采购入库信息入库重量
//                            BigDecimal bigDecimal2 = new BigDecimal(String.valueOf(subcontractReceipt.getWarehousingWeight()));
//                            BigDecimal bigDecimal3 = new BigDecimal(String.valueOf(subcontractReceiptDetail.getNetWeight()));
//                            String s1 = bigDecimal2.add(bigDecimal3).toString();
//                            subcontractReceipt.setWarehousingWeight(Double.parseDouble(s1));
//                            BigDecimal bigDecimal4 = new BigDecimal(subcontractReceipt.getWarehousingNum());
//                            BigDecimal bigDecimal5 = new BigDecimal(String.valueOf(subcontractReceiptDetail.getReceiptQuantity()));
//                            int i = Integer.parseInt(bigDecimal4.add(bigDecimal5).toString());
//                            subcontractReceipt.setWarehousingNum(i);
//                        }
//                    } else {
//                        if (subcontractReceipt.getActualQuantity() == null) {
//                            subcontractReceipt.setActualQuantity(String.valueOf(subcontractReceiptDetail.getReceiptQuantity()));
//                            //修改采购入库信息入库重量
//                            subcontractReceipt.setWarehousingWeight(subcontractReceiptDetail.getNetWeight());
//                            subcontractReceipt.setWarehousingNum(Integer.parseInt(String.valueOf(subcontractReceiptDetail.getReceiptQuantity())));
//
//                        } else {
//                            BigDecimal bigDecimal = new BigDecimal(subcontractReceipt.getActualQuantity());
//                            BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(subcontractReceiptDetail.getReceiptQuantity()));
//                            String s = bigDecimal.add(bigDecimal1).toString();
//                            subcontractReceipt.setActualQuantity(s);
//                            //修改采购入库信息入库重量
//                            BigDecimal bigDecimal2 = new BigDecimal(String.valueOf(subcontractReceipt.getWarehousingWeight()));
//                            BigDecimal bigDecimal3 = new BigDecimal(String.valueOf(subcontractReceiptDetail.getNetWeight()));
//                            String s1 = bigDecimal2.add(bigDecimal3).toString();
//                            subcontractReceipt.setWarehousingWeight(Double.parseDouble(s1));
//
//                            BigDecimal bigDecimal4 = new BigDecimal(subcontractReceipt.getWarehousingNum());
//                            BigDecimal bigDecimal5 = new BigDecimal(String.valueOf(subcontractReceiptDetail.getReceiptQuantity()));
//                            int i = Integer.parseInt(bigDecimal4.add(bigDecimal5).toString());
//                            subcontractReceipt.setWarehousingNum(i);
//                        }
//                    }
                    //设置入库仓
                    subcontractReceipt.setWarehousingWarehouse(pickingRestDbVo.getCkId());

                    pickingRestDbDto.setQuantityIdentification(subcontractReceipt.getPlannedWeight() + "/" + subcontractReceipt.getActualQuantity() + materialUnitDto.getUnitName());
                    pickingRestDbDto.setMessage("物料号码:" + subcontractReceiptDetail.getMaterialNumber() + "," + "数量:" + subcontractReceiptDetail.getNetWeight() + "," + "录入成功");
                    pickingRestDbDto.setUnit(subcontractReceiptDetail.getMaterialUnit());
                    pickingRestDbDto.setUnitDict(materialUnitDto.getUnitName());
                    pickingRestDbDto.setWarehouseNumber(String.valueOf(subcontractReceipt.getWarehousingNum()));

                    //修改仓库表中对应的数据状态
                    WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, subcontractReceiptDetail.getMaterialNumber()));
                    wmsStockInfo.setWsiMaterialStatus(2);
                    wmsStockInfo.setWsiWarehourse(String.valueOf(pickingRestDbVo.getCkId()));
                    wmsStockInfo.setWsiReservoirArea(String.valueOf(pickingRestDbVo.getKqId()));
                    wmsStockInfo.setWsiStorageLoaction(String.valueOf(pickingRestDbVo.getKwId()));
                    wmsStockInfo.setWsiWarehourseInfo(pickingRestDbVo.getCombinationName());
                    wmsStockInfo.setWsiConnectNum(subcontractReceipt.getSubcontractOrderNo());//关联单号
                    wmsStockInfo.setWsiDocNum(subcontractReceipt.getReceiptNo());//仓库关联单号
                    wmsStockInfo.setWsiMaterialGrade("1");
                    wmsStockInfoMapper.updateById(wmsStockInfo);
                    //修改明细状态
                    subcontractReceiptDetail.setStatus(2);
                    subcontractReceiptDetail.setWarehouseInBy(LoginHelper.getUsername());
                    subcontractReceiptDetail.setWarehouseInTime(new Date());
                    subcontractReceiptDetail.setWarehouseMessage(pickingRestDbVo.getCombinationName());
                    subcontractReceiptDetailMapper.updateById(subcontractReceiptDetail);
                    //校验该采购入库的全部明细状态是否都为已入库，如果不全是就修改为入库中，否则就修改为已完成
                    List<SubcontractReceiptDetail> subcontractReceiptDetailList = subcontractReceiptDetailMapper.selectList(new QueryWrapper<SubcontractReceiptDetail>().lambda().eq(SubcontractReceiptDetail::getSubcontractId, pickingRestDbVo.getId()));
                    boolean isTrue = true;
                    for (SubcontractReceiptDetail entity : subcontractReceiptDetailList) {
                        if (entity.getStatus() == 1) {
                            isTrue = false;
                            break;
                        }
                    }
                    //单位为千克
                    boolean b;
                    double aDouble = Double.parseDouble(subcontractReceipt.getActualQuantity());
                    double planWeight = Double.parseDouble(String.valueOf(subcontractReceipt.getPlannedWeight()));
//                    if ("2".equals(publicGoods.getMaterialUnit()) || "3".equals(publicGoods.getMaterialUnit())) {
//                        double plannedWeight = subcontractReceipt.getPlannedWeight();
//                        b = (int) Math.round(aDouble) >= (int) Math.round(plannedWeight);
//                    } else {
//                        int warehousingNum = subcontractReceipt.getWarehousingNum();
//                        b = (int) Math.round(aDouble) >= warehousingNum;
//                    }
                    b = (int) Math.round(aDouble) >= (int) Math.round(planWeight);

                    if (isTrue && b) {
                        subcontractReceipt.setStatus(3);
                    } else {
                        subcontractReceipt.setStatus(2);
                    }

                    //修改打印数据状态
                    List<SubcontractReceiptDetail> subcontractReceiptDetails = subcontractReceiptDetailMapper.selectList(new QueryWrapper<SubcontractReceiptDetail>().lambda().eq(SubcontractReceiptDetail::getSubcontractId, subcontractReceipt.getId()));

                    Map<String, List<SubcontractReceiptDetail>> collect = subcontractReceiptDetails.stream().collect(Collectors.groupingBy(SubcontractReceiptDetail::getBatchNo));
                    for (Map.Entry<String, List<SubcontractReceiptDetail>> materialGroupEntity : collect.entrySet()) {
                        boolean isAll = true;
                        for (SubcontractReceiptDetail entity1 : materialGroupEntity.getValue()) {
                            if (entity1.getStatus() != 2) {
                                isAll = false;
                                break;
                            }
                        }
                        IncomingMaterialPrinting incomingMaterialPrinting = incomingMaterialPrintingMapper.selectOne(new QueryWrapper<IncomingMaterialPrinting>()
                            .lambda().eq(IncomingMaterialPrinting::getReceiptNo, subcontractReceipt.getReceiptNo())
                            .eq(IncomingMaterialPrinting::getBatchNo, materialGroupEntity.getKey()));
                        if (isAll) {
                            //把对应的来料打印数据状态修改为已完成
                            incomingMaterialPrinting.setPrintStatus(4);
                        } else {
                            //把对应的来料打印数据状态修改为待入库
                            incomingMaterialPrinting.setPrintStatus(3);
                        }
                        incomingMaterialPrintingMapper.updateById(incomingMaterialPrinting);
                    }
                    //判断该单据在打印页面是否还存在未入库数据
                    String receiptNo = subcontractReceipt.getReceiptNo();
                    List<IncomingMaterialPrinting> incomingMaterialPrintings = incomingMaterialPrintingMapper.selectList(new QueryWrapper<IncomingMaterialPrinting>()
                        .lambda().eq(IncomingMaterialPrinting::getReceiptNo, receiptNo));
                    boolean printAll = true;
                    for (IncomingMaterialPrinting entity : incomingMaterialPrintings) {
                        if (entity.getPrintStatus() != 4) {
                            printAll = false;
                            break;
                        }
                    }
                    if (printAll) {
                        //计划量
                        double plannedWeight = subcontractReceipt.getPlannedWeight();
                        String actualQuantity = subcontractReceipt.getActualQuantity();
                        //实际量
                        double v = Double.parseDouble(actualQuantity);
                        //判断实际量是否大于等于计划量
                        if (v >= plannedWeight) {
                            subcontractReceipt.setStatus(4);
                        } else {
                            subcontractReceipt.setStatus(3);
                        }
                    } else {
                        subcontractReceipt.setStatus(2);
                    }
//                    // 数据回传至委外订单
//                    UpdateSubcontractingOrderDataVo updateSubcontractingOrderDataVo = new UpdateSubcontractingOrderDataVo();
//                    updateSubcontractingOrderDataVo.setSubcontractingOrderNumber(subcontractReceipt.getSubcontractOrderNo());
//                    updateSubcontractingOrderDataVo.setArriveWeight(subcontractReceiptDetail.getNetWeight());
//                    updateSubcontractingOrderDataVo.setStatus(subcontractReceipt.getStatus());
//                    orderFeignService.updateSubcontractingOrderData(updateSubcontractingOrderDataVo);

                    updateById(subcontractReceipt);
                    pickingRestDbDto.setCode("200");
                    return pickingRestDbDto;
                }
            }
            //批次入库
            if ("2".equals(pickingRestDbVo.getType())) {
                //如果是第一步，需要查询库位信息
                if (pickingRestDbVo.getExecutionOrder() == 1) {
                    WarehouseStringDto warehouseCode = warehouseService.getWarehouseCode(pickingRestDbVo.getInputValue());
                    if (warehouseCode.getCombinationName() == null) {
                        pickingRestDbDto.setMessage("该仓库不存在，请核实");
                        pickingRestDbDto.setCode("500");
                        return pickingRestDbDto;
                    }
                    pickingRestDbDto.setWarehouseMessage(warehouseCode.getCombinationName());
                    pickingRestDbDto.setCkId(warehouseCode.getCkId());
                    pickingRestDbDto.setKqId(warehouseCode.getKqId());
                    pickingRestDbDto.setKwId(warehouseCode.getKwId());
                    pickingRestDbDto.setCode("200");
                    return pickingRestDbDto;
                }
                //如果是第二步，需要根据批次号查询明细信息
                if (pickingRestDbVo.getExecutionOrder() == 2) {
                    List<SubcontractReceiptDetail> subcontractReceiptDetailList = subcontractReceiptDetailMapper.selectList(new QueryWrapper<SubcontractReceiptDetail>()
                        .lambda().eq(SubcontractReceiptDetail::getBatchNo, pickingRestDbVo.getInputValue())
                        .eq(SubcontractReceiptDetail::getSubcontractId, subcontractReceipt.getId())
                        .eq(SubcontractReceiptDetail::getStatus, 1));
                    if (subcontractReceiptDetailList.size() == 0) {
                        pickingRestDbDto.setCode("200");
                        pickingRestDbDto.setMessage("该批次下无待入库数据，请核实");
                        return pickingRestDbDto;
                    }
                    //净重总数
                    BigDecimal bigDecimalNetWeight = new BigDecimal(0);
                    //入库数量总数
                    BigDecimal bigDecimalWarehouseNum = new BigDecimal(0);
                    //循环明细信息
                    for (SubcontractReceiptDetail entity : subcontractReceiptDetailList) {
                        bigDecimalNetWeight = bigDecimalNetWeight.add(new BigDecimal(String.valueOf(entity.getNetWeight())));
                        bigDecimalWarehouseNum = bigDecimalWarehouseNum.add(new BigDecimal(String.valueOf(entity.getReceiptQuantity())));
                    }

//                    PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, subcontractReceipt.getMaterialCode()));
//                    //获取单位字典值
//                    List<SysDictData> unitArray = DictUtils.getDictCache("sys_material_unit");
//                    Map<String, String> unitMap = unitArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
                    MaterialUnitDto materialUnitDto = unitByCodeToMap.get(subcontractReceipt.getMaterialUnit());
                    if (subcontractReceipt.getActualQuantity() == null) {
                        subcontractReceipt.setActualQuantity(bigDecimalNetWeight.toString());
                        subcontractReceipt.setWarehousingWeight(Double.parseDouble(bigDecimalNetWeight.toString()));
                    } else {
                        BigDecimal bigDecimal = new BigDecimal(subcontractReceipt.getActualQuantity());
                        String s = bigDecimal.add(bigDecimalNetWeight).toString();
                        subcontractReceipt.setActualQuantity(s);

                        BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(subcontractReceipt.getWarehousingWeight()));
                        String s1 = bigDecimal1.add(bigDecimalNetWeight).toString();
                        subcontractReceipt.setWarehousingWeight(Double.parseDouble(s1));
                    }
//                    //判断单位
//                    if ("2".equals(publicGoods.getMaterialUnit())) {
//                        //如果单位是千克
//                        if (subcontractReceipt.getActualQuantity() == null) {
//                            subcontractReceipt.setActualQuantity(bigDecimalNetWeight.toString());
//                            subcontractReceipt.setWarehousingWeight(Double.parseDouble(bigDecimalNetWeight.toString()));
//                        } else {
//                            BigDecimal bigDecimal = new BigDecimal(subcontractReceipt.getActualQuantity());
//                            String s = bigDecimal.add(bigDecimalNetWeight).toString();
//                            subcontractReceipt.setActualQuantity(s);
//
//                            BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(subcontractReceipt.getWarehousingWeight()));
//                            String s1 = bigDecimal1.add(bigDecimalNetWeight).toString();
//                            subcontractReceipt.setWarehousingWeight(Double.parseDouble(s1));
//                        }
//                    } else if ("3".equals(publicGoods.getMaterialUnit())) {
//                        //如果单位是吨，若单位为吨，则实际量=入库重量（kg）/1000
//                        if (subcontractReceipt.getActualQuantity() == null) {
//                            BigDecimal bigDecimal = new BigDecimal(String.valueOf(bigDecimalNetWeight.toString()));
//                            BigDecimal divide = bigDecimal.divide(new BigDecimal("1000"));
//                            subcontractReceipt.setActualQuantity(divide.toString());
//                            //修改采购入库信息入库重量
//                            BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(subcontractReceipt.getWarehousingWeight()));
//                            String s1 = bigDecimal1.add(bigDecimalNetWeight).toString();
//                            subcontractReceipt.setWarehousingWeight(Double.parseDouble(s1));
//                        } else {
//                            BigDecimal bigDecimal = new BigDecimal(subcontractReceipt.getActualQuantity());
//                            BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(bigDecimalNetWeight.toString()));
//                            BigDecimal divide = bigDecimal1.divide(new BigDecimal("1000"));
//                            String s = bigDecimal.add(divide).toString();
//                            subcontractReceipt.setActualQuantity(s);
//                            //修改采购入库信息入库重量
//                            BigDecimal bigDecimal11 = new BigDecimal(String.valueOf(subcontractReceipt.getWarehousingWeight()));
//                            String s1 = bigDecimal11.add(bigDecimalNetWeight).toString();
//                            subcontractReceipt.setWarehousingWeight(Double.parseDouble(s1));
//                        }
//                    } else {
//                        if (subcontractReceipt.getActualQuantity() == null) {
//                            subcontractReceipt.setActualQuantity(bigDecimalWarehouseNum.toString());
//                            subcontractReceipt.setWarehousingWeight(Double.parseDouble(bigDecimalNetWeight.toString()));
//                        } else {
//                            BigDecimal bigDecimal = new BigDecimal(subcontractReceipt.getActualQuantity());
//                            String s = bigDecimal.add(bigDecimalWarehouseNum).toString();
//                            subcontractReceipt.setActualQuantity(s);
//
//                            BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(subcontractReceipt.getWarehousingWeight()));
//                            String s1 = bigDecimal1.add(bigDecimalNetWeight).toString();
//                            subcontractReceipt.setWarehousingWeight(Double.parseDouble(s1));
//                        }
//                    }
                    //设置入库数量
                    int warehousingNum1 = subcontractReceipt.getWarehousingNum();
                    if (warehousingNum1 == 0) {
                        subcontractReceipt.setWarehousingNum(subcontractReceiptDetailList.size());
                    } else {
                        subcontractReceipt.setWarehousingNum(warehousingNum1 + subcontractReceiptDetailList.size());
                    }
                    //设置入库仓
                    subcontractReceipt.setWarehousingWarehouse(pickingRestDbVo.getCkId());

                    pickingRestDbDto.setQuantityIdentification(subcontractReceipt.getPlannedWeight() + "/" + subcontractReceipt.getActualQuantity() + materialUnitDto.getUnitName());
                    pickingRestDbDto.setMessage("批次号:" + pickingRestDbVo.getInputValue() + "," + "数量:" + bigDecimalNetWeight + "," + "录入成功");
                    pickingRestDbDto.setUnit(subcontractReceiptDetailList.get(0).getMaterialUnit());
                    pickingRestDbDto.setUnitDict(materialUnitDto.getUnitName());
                    pickingRestDbDto.setWarehouseNumber(String.valueOf(bigDecimalWarehouseNum));


                    //修改仓库表中对应的数据状态
                    List<WmsStockInfo> wmsStockInfoList = wmsStockInfoMapper.selectList(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialBatch, pickingRestDbVo.getInputValue()));
                    List<WmsStockInfo> wmsStockInfoArrayList = new ArrayList<>();
                    for (WmsStockInfo entity : wmsStockInfoList) {
                        entity.setWsiMaterialStatus(2);
                        entity.setWsiWarehourse(String.valueOf(pickingRestDbVo.getCkId()));
                        entity.setWsiReservoirArea(String.valueOf(pickingRestDbVo.getKqId()));
                        entity.setWsiStorageLoaction(String.valueOf(pickingRestDbVo.getKwId()));
                        entity.setWsiWarehourseInfo(pickingRestDbVo.getCombinationName());
                        entity.setWsiConnectNum(subcontractReceipt.getSubcontractOrderNo());//关联单号
                        entity.setWsiDocNum(subcontractReceipt.getReceiptNo());//仓库关联单号
                        entity.setWsiMaterialGrade("1");
                        wmsStockInfoArrayList.add(entity);
                    }
                    wmsStockInfoMapper.updateBatchById(wmsStockInfoArrayList);
                    //修改明细状态
                    List<SubcontractReceiptDetail> detailList = new ArrayList<>();
                    for (SubcontractReceiptDetail subcontractReceiptDetail : subcontractReceiptDetailList) {
                        subcontractReceiptDetail.setStatus(2);
                        subcontractReceiptDetail.setWarehouseMessage(pickingRestDbVo.getCombinationName());
                        subcontractReceiptDetail.setWarehouseInBy(LoginHelper.getUsername());
                        subcontractReceiptDetail.setWarehouseInTime(new Date());
                        detailList.add(subcontractReceiptDetail);
                    }
                    subcontractReceiptDetailMapper.updateBatchById(detailList);

                    //校验该采购入库的全部明细状态是否都为已入库，如果不全是就修改为入库中，否则就修改为已完成
                    List<SubcontractReceiptDetail> receiptDetailList = subcontractReceiptDetailMapper.selectList(new QueryWrapper<SubcontractReceiptDetail>().lambda().eq(SubcontractReceiptDetail::getSubcontractId, pickingRestDbVo.getId()));
                    boolean isTrue = true;
                    for (SubcontractReceiptDetail entity : receiptDetailList) {
                        if (entity.getStatus() == 1) {
                            isTrue = false;
                            break;
                        }
                    }

                    //单位为千克
//                    boolean b;
//                    double aDouble = Double.parseDouble(subcontractReceipt.getActualQuantity());
//                    if ("2".equals(publicGoods.getMaterialUnit()) || "3".equals(publicGoods.getMaterialUnit())) {
//                        double plannedWeight = subcontractReceipt.getPlannedWeight();
//                        b = (int) Math.round(aDouble) >= (int) Math.round(plannedWeight);
//                    } else {
//                        int warehousingNum = subcontractReceipt.getWarehousingNum();
//                        b = (int) Math.round(aDouble) >= warehousingNum;
//                    }
                    boolean b;
                    double aDouble = Double.parseDouble(subcontractReceipt.getActualQuantity());
                    double planWeight = Double.parseDouble(String.valueOf(subcontractReceipt.getPlannedWeight()));
//                    if ("2".equals(publicGoods.getMaterialUnit()) || "3".equals(publicGoods.getMaterialUnit())) {
//                        double plannedWeight = subcontractReceipt.getPlannedWeight();
//                        b = (int) Math.round(aDouble) >= (int) Math.round(plannedWeight);
//                    } else {
//                        int warehousingNum = subcontractReceipt.getWarehousingNum();
//                        b = (int) Math.round(aDouble) >= warehousingNum;
//                    }
                    b = (int) Math.round(aDouble) >= (int) Math.round(planWeight);
                    if (isTrue && b) {
                        subcontractReceipt.setStatus(3);
                    } else {
                        subcontractReceipt.setStatus(2);
                    }
                    //修改委外打印状态
                    IncomingMaterialPrinting incomingMaterialPrinting = incomingMaterialPrintingMapper.selectOne(new QueryWrapper<IncomingMaterialPrinting>()
                        .lambda().eq(IncomingMaterialPrinting::getBatchNo, pickingRestDbVo.getInputValue()));
                    incomingMaterialPrinting.setPrintStatus(4);
                    incomingMaterialPrintingMapper.updateById(incomingMaterialPrinting);
                    //判断该单据在打印页面是否还存在未入库数据
                    String receiptNo = subcontractReceipt.getReceiptNo();
                    List<IncomingMaterialPrinting> incomingMaterialPrintings = incomingMaterialPrintingMapper.selectList(new QueryWrapper<IncomingMaterialPrinting>()
                        .lambda().eq(IncomingMaterialPrinting::getReceiptNo, receiptNo));
                    boolean printAll = true;
                    for (IncomingMaterialPrinting entity : incomingMaterialPrintings) {
                        if (entity.getPrintStatus() != 4) {
                            printAll = false;
                            break;
                        }
                    }
                    if (printAll) {
                        //计划量
                        double plannedWeight = subcontractReceipt.getPlannedWeight();
                        String actualQuantity = subcontractReceipt.getActualQuantity();
                        //实际量
                        double v = Double.parseDouble(actualQuantity);
                        //判断实际量是否大于等于计划量
                        if (v >= plannedWeight) {
                            subcontractReceipt.setStatus(4);
                        } else {
                            subcontractReceipt.setStatus(3);
                        }
                    } else {
                        subcontractReceipt.setStatus(2);
                    }

//                    // 数据回传至委外订单
//                    UpdateSubcontractingOrderDataVo updateSubcontractingOrderDataVo = new UpdateSubcontractingOrderDataVo();
//                    updateSubcontractingOrderDataVo.setSubcontractingOrderNumber(subcontractReceipt.getSubcontractOrderNo());
//                    updateSubcontractingOrderDataVo.setArriveWeight(Double.parseDouble(bigDecimalNetWeight.toString()));
//                    updateSubcontractingOrderDataVo.setStatus(subcontractReceipt.getStatus());
//                    orderFeignService.updateSubcontractingOrderData(updateSubcontractingOrderDataVo);
                    //修改采购入库状态
                    pickingRestDbDto.setCode("200");
                    updateById(subcontractReceipt);
                    return pickingRestDbDto;
                }
            }
            //库位撤销
            if ("3".equals(pickingRestDbVo.getType())) {
                //如果是第一步，需要查询库位信息
                if (pickingRestDbVo.getExecutionOrder() == 1) {
                    WarehouseStringDto warehouseCode = warehouseService.getWarehouseCode(pickingRestDbVo.getInputValue());
                    if (warehouseCode.getCombinationName() == null) {
                        pickingRestDbDto.setMessage("该仓库不存在，请核实");
                        pickingRestDbDto.setCode("500");
                        return pickingRestDbDto;
                    }
                    pickingRestDbDto.setWarehouseMessage(warehouseCode.getCombinationName());
                    pickingRestDbDto.setCkId(warehouseCode.getCkId());
                    pickingRestDbDto.setKqId(warehouseCode.getKqId());
                    pickingRestDbDto.setKwId(warehouseCode.getKwId());
                    pickingRestDbDto.setMessage("操作成功");
                    pickingRestDbDto.setCode("200");
                    return pickingRestDbDto;
                }
                //需要根据物料号码查询明细信息
                if (pickingRestDbVo.getExecutionOrder() == 2) {
                    WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, pickingRestDbVo.getInputValue()).eq(WmsStockInfo::getWsiMaterialStatus, 2));
                    if (wmsStockInfo == null) {
                        pickingRestDbDto.setMessage("撤销失败，请核实后再录入");
                        pickingRestDbDto.setCode("500");
                        return pickingRestDbDto;
                    }
                    wmsStockInfo.setWsiMaterialStatus(1);
                    wmsStockInfo.setWsiWarehourse("");
                    wmsStockInfo.setWsiReservoirArea("");
                    wmsStockInfo.setWsiStorageLoaction("");
                    wmsStockInfo.setWsiWarehourseInfo("");
                    wmsStockInfoMapper.updateById(wmsStockInfo);

//                    PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, subcontractReceipt.getMaterialCode()));
//                    //获取单位字典值
//                    List<SysDictData> unitArray = DictUtils.getDictCache("sys_material_unit");
//                    Map<String, String> unitMap = unitArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
                    MaterialUnitDto materialUnitDto = unitByCodeToMap.get(subcontractReceipt.getMaterialUnit());
                    //同时修改委外入库明细状态
                    SubcontractReceiptDetail subcontractReceiptDetail = subcontractReceiptDetailMapper.selectOne(new QueryWrapper<SubcontractReceiptDetail>().lambda().eq(SubcontractReceiptDetail::getMaterialNumber, pickingRestDbVo.getInputValue()));
                    subcontractReceiptDetail.setStatus(1);
                    subcontractReceiptDetail.setWarehouseMessage("");
                    subcontractReceiptDetailMapper.updateById(subcontractReceiptDetail);

                    //判断单位
//                    if ("2".equals(publicGoods.getMaterialUnit())) {
//                        //如果单位是千克
//                        String actualQuantity = subcontractReceipt.getActualQuantity();
//                        double warehousingWeight = subcontractReceipt.getWarehousingWeight();
//                        //实际量
//                        BigDecimal actualSubtract = new BigDecimal(actualQuantity).subtract(new BigDecimal(String.valueOf(subcontractReceiptDetail.getNetWeight())));
//                        //入库重量
//                        BigDecimal warehousingSubtract = new BigDecimal(String.valueOf(warehousingWeight)).subtract(new BigDecimal(String.valueOf(subcontractReceiptDetail.getNetWeight())));
//                        subcontractReceipt.setActualQuantity(actualSubtract.toString());
//                        subcontractReceipt.setWarehousingWeight(Double.parseDouble(warehousingSubtract.toString()));
//                    } else if ("3".equals(publicGoods.getMaterialUnit())) {
//                        //如果单位是吨，若单位为吨，则实际量=入库重量（kg）/1000
//                        BigDecimal bigDecimal = new BigDecimal(String.valueOf(subcontractReceiptDetail.getNetWeight()));
//                        BigDecimal divide = bigDecimal.divide(new BigDecimal("1000"));
//                        String actualQuantity = subcontractReceipt.getActualQuantity();
//                        double warehousingWeight = subcontractReceipt.getWarehousingWeight();
//                        //实际量
//                        BigDecimal actualSubtract = new BigDecimal(actualQuantity).subtract(divide);
//                        //入库重量
//                        BigDecimal warehousingSubtract = new BigDecimal(String.valueOf(warehousingWeight)).subtract(new BigDecimal(String.valueOf(subcontractReceiptDetail.getNetWeight())));
//                        subcontractReceipt.setActualQuantity(actualSubtract.toString());
//                        subcontractReceipt.setWarehousingWeight(Double.parseDouble(warehousingSubtract.toString()));
//                    } else {
//
//                        BigDecimal bigDecimal = new BigDecimal(String.valueOf(subcontractReceiptDetail.getNetWeight()));
//                        BigDecimal divide = bigDecimal.divide(new BigDecimal("1000"));
//                        String actualQuantity = subcontractReceipt.getActualQuantity();
//                        double warehousingWeight = subcontractReceipt.getWarehousingWeight();
//                        //实际量
//                        BigDecimal actualSubtract = new BigDecimal(actualQuantity).subtract(divide);
//                        //入库重量
//                        BigDecimal warehousingSubtract = new BigDecimal(String.valueOf(warehousingWeight)).subtract(new BigDecimal(String.valueOf(subcontractReceiptDetail.getNetWeight())));
//                        subcontractReceipt.setActualQuantity(actualSubtract.toString());
//                        subcontractReceipt.setWarehousingWeight(Double.parseDouble(warehousingSubtract.toString()));
//
//                    }

                    //修改采购入库状态
                    subcontractReceipt.setStatus(2);
                    subcontractReceipt.setWarehousingNum(subcontractReceipt.getWarehousingNum() - 1);
//                    double warehousingWeight = subcontractReceipt.getWarehousingWeight();
//                    double netWeight = subcontractReceiptDetail.getNetWeight();
//                    BigDecimal subtract = new BigDecimal(String.valueOf(warehousingWeight)).subtract(new BigDecimal(String.valueOf(netWeight)));
//                    subcontractReceipt.setWarehousingWeight(Double.parseDouble(subtract.toString()));


//                    // 数据回传至委外订单
//                    UpdateSubcontractingOrderDataVo updateSubcontractingOrderDataVo = new UpdateSubcontractingOrderDataVo();
//                    updateSubcontractingOrderDataVo.setSubcontractingOrderNumber(subcontractReceipt.getSubcontractOrderNo());
//                    updateSubcontractingOrderDataVo.setArriveWeight(subcontractReceiptDetail.getNetWeight());
//                    updateSubcontractingOrderDataVo.setStatus(subcontractReceipt.getStatus());
//                    orderFeignService.updateSubcontractingOrderDataDelete(updateSubcontractingOrderDataVo);

                    updateById(subcontractReceipt);

                    //设置返回信息
                    pickingRestDbDto.setMessage("物料号码:" + pickingRestDbVo.getInputValue() + "," + "净重:" + subcontractReceiptDetail.getNetWeight() + "kg" + "," + "数量:" + "1" + "," + "撤销成功");
                    pickingRestDbDto.setQuantityIdentification(subcontractReceipt.getPlannedWeight() + "/" + subcontractReceipt.getActualQuantity() + materialUnitDto.getUnitName());
                    pickingRestDbDto.setUnit(subcontractReceiptDetail.getMaterialUnit());
                    pickingRestDbDto.setUnitDict(materialUnitDto.getUnitName());
                    pickingRestDbDto.setWarehouseNumber(String.valueOf(subcontractReceipt.getWarehousingNum()));
                    pickingRestDbDto.setCode("200");
                    return pickingRestDbDto;
                }
            }
        } else {
            pickingRestDbDto.setMessage("只能操作待入库、入库中、部分入库得数据");
            pickingRestDbDto.setCode("500");
            return pickingRestDbDto;
        }
        pickingRestDbDto.setCode("500");
        pickingRestDbDto.setMessage("步骤错误");
        return pickingRestDbDto;
    }

    /**
     * 委外入库状态及数据修改（委外订单关结时 fegin调用）
     *
     * @param updateReceiptStatusVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateSubcontractReceiptStatus(UpdateReceiptStatusVo updateReceiptStatusVo) {

        List<SubcontractReceipt> subcontractReceipts = subcontractReceiptMapper.selectList(new QueryWrapper<SubcontractReceipt>().lambda().eq(SubcontractReceipt::getSubcontractOrderNo, updateReceiptStatusVo.getPurchaseOrderNo()));
        if (subcontractReceipts.size() > 0) {
            for (SubcontractReceipt entity : subcontractReceipts) {
                //判断来料打印中是否都已完成，否则不让关结
                List<IncomingMaterialSubcontractPrinting> incomingMaterialPrintings = incomingMaterialSubcontractPrintingMapper.selectList(new QueryWrapper<IncomingMaterialSubcontractPrinting>().lambda()
                    .eq(IncomingMaterialSubcontractPrinting::getReceiptNo, entity.getReceiptNo())
                    .ne(IncomingMaterialSubcontractPrinting::getPrintStatus, 4));

                if (incomingMaterialPrintings.size() != 0) {
                    throw new GlobalException("存在未完成的来料打印单,不能关结");
                }
                //已完成、已关结不可重复关结；
                if (entity.getStatus() != 4 || entity.getStatus() != 5) {
                    //待入库、部分入库状态的单据关结后，单据状态更新为“已关结”，无影响；
                    if (entity.getStatus() == 1 || entity.getStatus() == 3) {
                        entity.setStatus(updateReceiptStatusVo.getUpdateValue());
                    }
                    // 入库中的单据关结后，单据状态更新为“已关结”，已扫描过的条码为在库（委外入库未扫描的条码从库存中删除）
                    if (entity.getStatus() == 2) {
                        List<SubcontractReceiptDetail> subcontractReceiptDetails = subcontractReceiptDetailMapper.selectList(new QueryWrapper<SubcontractReceiptDetail>().lambda().eq(SubcontractReceiptDetail::getSubcontractId, entity.getId()));
                        if (subcontractReceiptDetails.size() > 0) {
                            //获取未扫描的明细数据
                            List<String> materialNumberList = subcontractReceiptDetails.stream()
                                .filter(t -> t.getStatus() == 1)
                                .map(SubcontractReceiptDetail::getMaterialNumber)
                                .collect(Collectors.toList());
                            //将对应号码的数据在仓库中进行删除
                            List<WmsStockInfo> wmsStockInfos = wmsStockInfoMapper.selectList(new QueryWrapper<WmsStockInfo>().lambda().in(WmsStockInfo::getWsiMaterialNumber, materialNumberList));
                            wmsStockInfoMapper.deleteBatchIds(wmsStockInfos);
                        }
                        entity.setStatus(updateReceiptStatusVo.getUpdateValue());
                    }
                } else {
                    throw new GlobalException("已完成、已关结不可重复关结");
                }
            }
            return updateBatchById(subcontractReceipts);
        } else {
            throw new GlobalException("没有查询到相关采购入库单,请核实!");
        }
    }

    /**
     * 入库打印
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean warehousInspection(WarehousInspectionVo warehousInspectionVo) {
        return false;
    }

    /**
     * 批次号生成
     */
    public String batchNoGenerate() {
        String batchNo = "";
        String prefix = "WW";
        //查询缓存
        Object cacheObject = RedisUtils.getCacheObject(VariousKeyEnum.getValue(1));
        if (cacheObject == null) {
            String num = "0001";
            SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
            String format = sf.format(new Date());
            batchNo = prefix + format + num;
            //放入缓存
            RedisUtils.setCacheObject(VariousKeyEnum.getValue(1), num);
            return batchNo;
        }
        String s = cacheObject.toString();
        String s1 = addOne(s);
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
        String format = sf.format(new Date());
        batchNo = format + s1;
        //放入缓存
        RedisUtils.setCacheObject(VariousKeyEnum.getValue(1), s1);
        return batchNo;
    }

    //字符串末尾加1
    public String addOne(String testStr) {
        //根据不是数字的字符拆分字符串
        String[] strs = testStr.split("[^0-9]");
        //取出最后一组数字
        String numStr = strs[strs.length - 1];
        //如果最后一组没有数字(也就是不以数字结尾)，抛NumberFormatException异常
        if (numStr != null && numStr.length() > 0) {
            //取出字符串的长度
            int n = numStr.length();
            //将该数字加一
            int num = Integer.parseInt(numStr) + 1;
            String added = String.valueOf(num);
            n = Math.min(n, added.length());
            //拼接字符串
            return testStr.subSequence(0, testStr.length() - n) + added;
        } else {
            throw new NumberFormatException();
        }
    }
}
